package servlet;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import pub.fjf.http.Application;
import pub.fjf.http.ApplicationServer;
import pub.fjf.http.HttpServlet;
import pub.fjf.http.HttpServletRequest;
import pub.fjf.http.HttpServletResponse;
import pub.fjf.http.WebProject;
import pub.fjf.tools.Json;
import pub.fjf.tools.StringTools;

public class ServerApplication extends HttpServlet {

	/**
	 * json={projectIndex:Number,order:String("Show"|"Remove"|"Add"|"SetUrl"|"Get"|"Change"),
	 * fileName,context}
	 */
	private void handleServletOrder(HttpServletRequest req, HttpServletResponse resp,Json json) {
		int projectIndex=json.getMember("projectIndex").toInt();
		String order=json.getMember("order").getValueString();
		String fileName=json.getMember("fileName").getValueString();
		String context=json.getMember("context").getValueString();
		WebProject project=req.getClient().getServer().getWebProjects().get(projectIndex);
		String rootPath=project.getRootPath();
		ApplicationServer applicationServer=(ApplicationServer) project.getDefaultFilters().get(ApplicationServer.class.getName());
		String applicationMapPath=applicationServer.getApplicationMapPath();
		if(rootPath.length()>0&&rootPath.charAt(rootPath.length()-1)!='/') {
			applicationMapPath='/'+applicationMapPath;
		}
		applicationMapPath=rootPath+applicationMapPath;
		Json applicationMapJson=new Json(StringTools.readAsPath(applicationMapPath));
		if(applicationMapJson.getTypeCode()==Json.TYPE_UNDEFINED) {
			applicationMapJson=Json.CreateArrayJson();
		}
		if(order.equals("Show")) {
			resp.sendData(applicationMapJson.toString(), "text/txt");
		}else {
			String javaPath=rootPath;
			if(rootPath.length()>0&&rootPath.charAt(rootPath.length()-1)!='/') {
				javaPath=javaPath+"/";
			}
			javaPath=javaPath+"src/application/"+fileName;
			String classPath=javaPath+".class";
			javaPath=javaPath+".java";
			Json applicationJson=null;
			int index=-1;
			for(int i=0;i<applicationMapJson.getElementCount();i++) {
				Json sJson=applicationMapJson.getElement(i);
				if(sJson.getMember("applicationName").getValueString().equals(fileName)) {
					applicationJson=sJson;
					index=i;
					break;
				}
			}
			if(order.equals("SetId")) {
				String oldId=applicationJson.getMember("id").getValueString();
				applicationJson.setMember("id", Json.CreateStringJson(context));
				StringTools.writeAsPath(applicationMapPath, applicationJson.toString(true));
				Application application=applicationServer.getApplicationMap().remove(oldId);
				applicationServer.addApplication(context, application);
				resp.sendData(applicationJson.toString(), "text/txt");
				return;
			}else if(order.equals("Get")) {
				String code=StringTools.readAsPath(javaPath);
				resp.sendData(Json.CreateStringJson(code).toString(), "text/txt");
				return;
			}else if(order.equals("Add")) {
				File file=new File(javaPath);
				if(file.exists()) {
					resp.setStateCode("500");
					resp.sendResponse();
					return;
				}
				try {
					if(file.createNewFile()) {
						StringBuffer sb=new StringBuffer();
						String manageRootPath=req.getClient().getWebProject().getRootPath();
						if(manageRootPath.length()>0&&manageRootPath.charAt(manageRootPath.length()-1)!='/') {
							manageRootPath+="/";
						}
						String codePath=manageRootPath+"modes/codes/Application1.code";
						sb.append(StringTools.readAsPath(codePath));
						sb.append(fileName);
						codePath=manageRootPath+"modes/codes/Application2.code";
						sb.append(StringTools.readAsPath(codePath));
						FileOutputStream fos=null;
						fos=new FileOutputStream(file);
						fos.write(sb.toString().getBytes(req.getCharset()));
						fos.close();
						applicationJson=Json.CreateObjectJson();
						applicationJson.setMember("id", Json.CreateStringJson(fileName));
						applicationJson.setMember("className", Json.CreateStringJson("application."+fileName));
						applicationJson.setMember("content", Json.CreateStringJson("src/application"));
						applicationJson.setMember("applicationName", Json.CreateStringJson(fileName));
						applicationMapJson.addElement(applicationJson);
					}else {
						resp.setStateCode("500");
						resp.sendResponse();
						return;
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					resp.setStateCode("500");
					resp.sendResponse();
					return;
				}
			}else if(index<0){
				resp.setStateCode("400");
				resp.sendResponse();
				return;
			}else if(order.equals("Remove")){
				File file=new File(javaPath);
				File classFile=new File(classPath);
				file.delete();
				classFile.delete();
				applicationMapJson.removeElement(index);
			}else if(order.equals("Change")) {
				File file=new File(javaPath);
				File classFile=new File(classPath);
				try {
					file.delete();
					classFile.delete();
					if(file.createNewFile()) {
						FileOutputStream fos=null;
						fos=new FileOutputStream(file);
						fos.write(context.getBytes());
						fos.close();
					}else {
						resp.setStateCode("500");
						resp.sendResponse();
						return;
					}
				} catch (IOException e) {
					// TODO Auto-generated catch block
					resp.setStateCode("500");
					resp.sendResponse();
					return;
				}
			}
			applicationServer.getApplicationMap().clear();
			try {
				applicationServer.configApplicationMap(applicationMapJson);
				StringTools.writeAsPath(applicationMapPath, applicationMapJson.toString(true));
				String servlrtMapPath=applicationServer.getServletMapPath();
				if(rootPath.length()>0&&rootPath.charAt(rootPath.length()-1)!='/') {
					servlrtMapPath='/'+servlrtMapPath;
				}
				servlrtMapPath=rootPath+servlrtMapPath;
				Json servlrtMapJson=new Json(StringTools.readAsPath(servlrtMapPath));
				if(servlrtMapJson.getTypeCode()==Json.TYPE_UNDEFINED) {
					servlrtMapJson=Json.CreateArrayJson();
				}
				applicationServer.configServletMap(servlrtMapJson);
				StringTools.writeAsPath(servlrtMapPath, servlrtMapJson.toString(true));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				resp.setStateCode("500");
				resp.sendData(e.toString(), "text/txt");
				return;
			}
			if(order.equals("Change")){
				String code=StringTools.readAsPath(javaPath);
				resp.sendData(Json.CreateStringJson(code).toString(), "text/code");
			}else {
				resp.sendData(applicationMapJson.toString(), "text/txt");
			}
		}
	}
	@Override
	public void doGet(HttpServletRequest req, HttpServletResponse resp) {
		// TODO Auto-generated method stub
		int projectIndex=-1;
		try {
			Json reqJson=new Json(req.getParameter());
			if(reqJson.getTypeCode()==Json.TYPE_NUMBER) {
				projectIndex=reqJson.toInt();
				Json json=Json.CreateObjectJson();
				json.setMember("projectIndex", Json.CreateNumberJson(projectIndex));
				json.setMember("order", Json.CreateStringJson("Show"));
				this.handleServletOrder(req, resp, json);
			}else {
				resp.setStateCode("500");
				resp.sendResponse();
			}
		}catch(Exception e) {
			resp.setStateCode("500");
			resp.sendResponse();
		}
	}

	@Override
	public void doPost(HttpServletRequest req, HttpServletResponse resp) {
		// TODO Auto-generated method stub
		StringBuffer sb=new StringBuffer();
		sb.append(req.getBody());
		while(req.haveData()) {
			try {
				sb.append(new String(req.readData(),req.getCharset()));
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		this.handleServletOrder(req, resp, new Json(sb.toString()));
	}

}
